<?php
namespace Plu\Library\Services;

use Phalcon\Config,
    Plu\Bodkin\Zipkin;

class GrpcFactory extends ServiceBase {
    protected $services = [];

    protected $registry;

    private $zipkin;

    public function __construct($name = null) {
        $this->createRegistry();

        if (!is_null($name)) {
            $this->enableZipkin($name);
        }
    }

    public function createRegistry() {
        $grpcConfig = $this->config->get("grpc");
        if (!$grpcConfig instanceof Config) {
            return;
        }

        $type = $grpcConfig->type;
        if ($type == 'consul') {
            $registry = new \Plu\Grpc\Registries\Consul($grpcConfig->hosts);
        } elseif ($type == "zookeeper") {
            $registry = new \Plu\Grpc\Registries\Zookeeper($grpcConfig->hosts);
        } elseif ($type == 'locale') {
            $registry = new \Plu\Grpc\Registries\Locale($grpcConfig->hosts);
        }

        if (!isset($registry)) {
            throw new \Exception(sprintf("Create grpc registry failed, because type: %s", $type));
        }
        $this->registry = $registry;
    }

    private function enableZipkin($name) {
        $grpcConfig = $this->config->get("grpc");
        if (!$grpcConfig instanceof Config) {
            return;
        }

        if (!$grpcConfig->enableTracing) {
            return;
        }
        
        if ($grpcConfig->traceReporter != 'redis') {
            return;
        }

        //get redis config
        $redisName = $grpcConfig->traceReporterOptions->redisName;
        $redisConfig = $this->config->get('redis')->get($redisName);
        if (empty($redisConfig)) {
            return;
        }

        $zipkin = Zipkin::newZipkin($name, [
            "report" => [
                'type'      => 'redis',
                'host'      => $redisConfig->hostname, 
                'port'      => $redisConfig->port, 
                'timeout'   => $redisConfig->timeout
            ]
        ]);

        $this->zipkin = $zipkin;
    }

    public function service($serviceName) {
        if (isset($this->services[$serviceName])) {
            return $this->services[$serviceName];
        }

        $client = \Plu\Grpc\Factory::getClient($this->registry, $serviceName, $this->zipkin);
        $this->services[$serviceName] = $client;

        return $client;
    }
}
